<?php

declare(strict_types=1);

namespace app\service\user;

use app\model\AuthRole;
use app\model\AuthUserRole;
use think\facade\Log;

class UserRoleManager
{
    /**
     * 确保用户具备指定角色（按照角色标识），若角色不存在则跳过。
     *
     * @param int $userId
     * @param array<int, array<string, mixed>> $roles [[slug => string, org_id => ?int, region_id => ?int], ...]
     */
    public static function ensureRoles(int $userId, array $roles): void
    {
        if ($userId <= 0 || empty($roles)) {
            return;
        }

        $uniqueSlugs = array_values(array_unique(array_filter(array_map(
            static fn($role) => is_array($role) ? (string) ($role['slug'] ?? '') : '',
            $roles
        ), static fn($slug) => $slug !== '')));

        if (empty($uniqueSlugs)) {
            return;
        }

        $roleMap = AuthRole::whereIn('slug', $uniqueSlugs)->column('id', 'slug');
        if (empty($roleMap)) {
            Log::warning('assign_roles_missing_slugs', [
                'user_id' => $userId,
                'slugs' => $uniqueSlugs,
            ]);
            return;
        }

        $now = date('Y-m-d H:i:s');

        foreach ($roles as $role) {
            if (!is_array($role)) {
                continue;
            }
            $slug = (string) ($role['slug'] ?? '');
            if ($slug === '' || !isset($roleMap[$slug])) {
                continue;
            }

            $orgId = array_key_exists('org_id', $role)
                ? (is_numeric($role['org_id']) ? (int) $role['org_id'] : null)
                : null;
            $regionId = array_key_exists('region_id', $role)
                ? (is_numeric($role['region_id']) ? (int) $role['region_id'] : null)
                : null;

            $query = AuthUserRole::withTrashed()
                ->where('user_id', $userId)
                ->where('role_id', (int) $roleMap[$slug]);

            if ($orgId !== null) {
                $query->where('org_id', $orgId);
            } else {
                $query->whereNull('org_id');
            }

            /** @var AuthUserRole|null $binding */
            $binding = $query->find();

            if ($binding) {
                if ($binding->delete_time !== null) {
                    $binding->restore();
                }

                $update = [
                    'status' => 1,
                    'update_time' => $now,
                ];

                if ($orgId !== null) {
                    $update['org_id'] = $orgId;
                }

                if ($regionId !== null) {
                    $update['region_id'] = $regionId;
                }

                $binding->save($update);
                continue;
            }

            AuthUserRole::create([
                'user_id' => $userId,
                'role_id' => (int) $roleMap[$slug],
                'org_id' => $orgId,
                'region_id' => $regionId,
                'status' => 1,
            ]);
        }
    }
}
